package org.infodavid.common.model;

import java.io.Serializable;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.joda.time.DateTime;
import org.junit.Assert;
import org.junit.Test;

import org.infodavid.common.IBuilder;
import org.infodavid.common.dto.IOrganizationListItem.ELegalForm;
import org.infodavid.common.ejb.OrganizationBean;
import org.infodavid.common.model.components.IEMail;
import org.infodavid.common.model.components.ILocation;
import org.infodavid.common.model.components.IPhone;
import org.infodavid.common.model.components.IUri;
import org.infodavid.common.persistence.PersistenceSession;

/**
 * The Class OrganizationTest.
 */
public class OrganizationTest extends AbstractBeanTest<IOrganization> {

	/** The person test. */
	private final PersonTest personTest = new PersonTest(this);

	/**
	 * Instantiates a new organization test.
	 */
	public OrganizationTest() {
		super();
	}

	/**
	 * Instantiates a new organization test.
	 * @param mainTest the main test
	 */
	public OrganizationTest(final AbstractPersistenceTest mainTest) {
		super(mainTest);
	}

	/**
	 * Populate.
	 * @param count the count
	 * @return the collection< test data>
	 * @throws Exception the exception
	 */
	@Override
	protected List<IOrganization> doCreate(final int count) throws Exception {
		final IBuilder<IOrganization> builder =
		    ModelFactory.getInstance().getBuilder(IOrganization.class);
		final List<IOrganization> items = new ArrayList<IOrganization>(count);
		final Iterator<IPerson> persons = personTest.populate(count).iterator();
		final Iterator<ILocation> locations = TestUtil.createLocations(count).iterator();
		final IBuilder<IEMail> emailBuilder = ModelFactory.getInstance().getBuilder(IEMail.class);
		final IBuilder<IUri> uriBuilder = ModelFactory.getInstance().getBuilder(IUri.class);
		final IBuilder<IPhone> phoneBuilder = ModelFactory.getInstance().getBuilder(IPhone.class);
		IOrganization parent = null;
		IOrganization item;
		IEMail email;
		IPhone phone;
		IUri uri;
		long key;

		for (int i = 0; i < count; i++) {
			item = builder.create();
			key = System.nanoTime();

			item.setName("item-" + key);
			item.setComment("comment-" + key);
			item.setIdentity("identity-" + key);
			item.setRegistrationDate(new DateTime());
			item.setLegalForm(ELegalForm.SA);
			item.setBusinessType("Business" + key);
			item.setDirector(persons.next());

			item.getLocations().add(locations.next());

			email = emailBuilder.create();

			email.setValue(item.getName() + "@domain.com");
			item.getEmails().add(email);

			uri = uriBuilder.create();

			uri.setValue(new URI("http://www.darpa.mil/" + key));
			item.getWebSites().add(uri);

			phone = phoneBuilder.create();

			phone.setValue("0123456789");
			item.getPhones().add(phone);

			item.getProperties().addData("key1", "value1");
			item.getProperties().addData("key2", "value2");

			if (i == 0) {
				parent = item;
			}
			else {
				item.setMainSite(parent);
			}

			items.add(item);
		}

		return items;
	}

	/**
	 * See super class or interface. (non-Javadoc)
	 * @see org.infodavid.common.model.AbstractBeanTest#getEntityClass()
	 */
	@Override
	public Class<OrganizationBean> getEntityClass() {
		return OrganizationBean.class;
	}

	/**
	 * See super class or interface. (non-Javadoc)
	 * @see org.infodavid.common.model.AbstractBeanTest#getEntityName()
	 */
	@Override
	public String getEntityName() {
		return IOrganization.class.getSimpleName();
	}

	/**
	 * Test remove entity.
	 * @throws Exception the exception
	 */
	@Test
	@Override
	public final void testRemoveEntity() throws Exception {
		final PersistenceSession session = getSession();
		final Collection<IOrganization> inserted = getTestData();
		final IOrganization item =
		    inserted.toArray(new IOrganization[inserted.size()])[inserted.size() - 1];
		final Serializable key = item.getKey();

		session.removeEntity(item, null);
		session.getTransaction().commit();

		Assert.assertNull("Not all data has been inserted",
		    session.findEntity(getEntityClass(), null, key));
	}
}
